package cn.wjssl.domain.award.service;

import cn.wjssl.domain.award.event.SendAwardMessageEvent;
import cn.wjssl.domain.award.model.aggregate.UserAwardRecordAggregate;
import cn.wjssl.domain.award.model.entity.DistributeAwardEntity;
import cn.wjssl.domain.award.model.entity.UserAwardRecordEntity;
import cn.wjssl.domain.award.model.valobj.TaskStateVO;
import cn.wjssl.domain.award.repository.IAwardRepository;
import cn.wjssl.domain.award.model.entity.TaskEntity;
import cn.wjssl.domain.award.service.distribute.IDistributeAward;
import cn.wjssl.types.event.BaseEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @Author：lxd
 * @Description 奖品服务
 * @Date：2025/2/25
 */

@Slf4j
@Service
public class AwardService implements IAwardService {

    @Resource
    private IAwardRepository repository;
    @Resource
    private SendAwardMessageEvent event;

    // 奖品类型处理器
    @Resource
    private Map<String, IDistributeAward> distributeAwardMap;

    // 抽奖, 保存抽奖record(create), 并推送记录到task
    @Override
    public void saveUserAwardRecord(UserAwardRecordEntity userAwardRecordEntity) {

        // 构建mq消息体
        BaseEvent.EventMessage<SendAwardMessageEvent.SendAwardMessage> sendMsg = event.buildEventMessage(
                SendAwardMessageEvent.SendAwardMessage.builder()
                        .userId(userAwardRecordEntity.getUserId())
                        .awardId(userAwardRecordEntity.getAwardId())
                        .awardTitle(userAwardRecordEntity.getAwardTitle())
                        .orderId(userAwardRecordEntity.getOrderId())
                        .awardConfig(userAwardRecordEntity.getAwardConfig())
                        .build()
        );

        // 构建task对象
        TaskEntity taskEntity = new TaskEntity();
        taskEntity.setUserId(userAwardRecordEntity.getUserId());
        taskEntity.setTopic(event.topic());
        taskEntity.setMessageId(sendMsg.getId());
        taskEntity.setMessage(sendMsg);     // 将BaseEvent消息对象存入task实体, 在映射PO时, 通过Json序列化成String
        taskEntity.setState(TaskStateVO.create);    // 最开始是创建

        // 构建聚合对象
        UserAwardRecordAggregate userAwardRecordAggregate = UserAwardRecordAggregate.builder()
                .taskEntity(taskEntity)
                .userAwardRecordEntity(userAwardRecordEntity)
                .build();

        // 通过事务, 更新award_record表和task表, 推送mq消息
        repository.saveUserAwardRecord(userAwardRecordAggregate);
    }

    /**
     * 奖品发放, 更新中奖记录(completed), 和对应的奖品方式
     * 如果是积分, 就调用对应的奖品方法实现类bean(user_credit_random), 更新中奖记录, 并更新用户积分账户
     * 如果是其他奖品, todo
     * @param distributeAwardEntity
     */
    @Override
    public void distributeAward(DistributeAwardEntity distributeAwardEntity) {
        // 1. 根据awardId, 获取奖品类型 award_key
        String awardKey = repository.queryAwardKey(distributeAwardEntity.getAwardId());
        if (null == awardKey) {
            log.error("分发奖品，奖品ID不存在。awardKey:{}", awardKey);
            return;
        }

        // 2. 获取对应奖品类型的处理器
        IDistributeAward distributeAward = distributeAwardMap.get(awardKey);
        if (null == distributeAward) {
            log.error("分发奖品，对应的服务不存在。awardKey:{}", awardKey);
            throw new RuntimeException("分发奖品，奖品" + awardKey + "对应的服务不存在");
        }

        // 发放奖品
        distributeAward.giveOutPrizes(distributeAwardEntity);

    }
}
